from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from database import get_db
from schemas.payment_schemas import PaymentCreate, PaymentUpdate, PaymentResponse
from services.payment_service import (
    get_payment,
    get_payments,
    create_payment,
    update_payment,
    delete_payment,
    get_payments_by_patient, get_paid_payments_by_patient
)
from services.auth_service import require_user
from models.user_models import UserType

router = APIRouter(prefix="/payments", tags=["payments"])

@router.get("/", response_model=list[PaymentResponse])
def read_payments(skip: int = 0, limit: int = 100, db: Session = Depends(get_db),
                 user=Depends(require_user(UserType.ADMIN,UserType.PATIENT))):
    payments = get_payments(db, skip=skip, limit=limit)
    return payments

@router.post("/", response_model=PaymentResponse)
def create_new_payment(payment: PaymentCreate, db: Session = Depends(get_db),
                     user=Depends(require_user(UserType.ADMIN, UserType.PATIENT))): ##权限暂定
    return create_payment(db, payment)

@router.get("/{payment_id}", response_model=PaymentResponse)        ##暂定接口
def read_payment(payment_id: int, db: Session = Depends(get_db),
                user=Depends(require_user(UserType.ADMIN, UserType.PATIENT))):
    return get_payment(db, payment_id)

@router.put("/{payment_id}", response_model=PaymentResponse)        ##用户缴费后是否缴费从N->Y
def update_existing_payment(
    payment_id: int, 
    payment: PaymentUpdate,
    db: Session = Depends(get_db),
    payload: dict = Depends(require_user(UserType.ADMIN, UserType.PATIENT))
):
    # 从payload中获取用户类型和ID
    user_type = UserType.from_str(payload.get("user_type"))
    user_ref_id = int(payload.get("user_ref_id"))
    
    # 获取要更新的支付记录
    db_payment = get_payment(db, payment_id)
    
    # 如果是患者用户
    if user_type == UserType.PATIENT:
        # 1. 验证是否是自己记录
        if db_payment.patient_ID != user_ref_id:
            raise HTTPException(
                status_code=403,
                detail="Patients can only update their own payments"
            )
        
        # 2. 验证是否只修改了pay_y_n字段
        update_data = payment.dict(exclude_unset=True)
        if len(update_data) != 1 or 'pay_y_n' not in update_data:
            raise HTTPException(
                status_code=403,
                detail="Patients can only update payment status (pay_y_n)"
            )
    
    # 更新记录
    update_data = payment.dict(exclude_unset=True)
    for key, value in update_data.items():
        setattr(db_payment, key, value)
    
    db.add(db_payment)
    db.commit()
    db.refresh(db_payment)
    return db_payment

@router.delete("/{payment_id}")
def delete_existing_payment(payment_id: int, db: Session = Depends(get_db),
                          user=Depends(require_user(UserType.ADMIN))):
    return delete_payment(db, payment_id)

@router.get("/patient/{patient_id}", response_model=list[PaymentResponse])  ##获取单个
def read_patient_payments(
    patient_id: int, 
    db: Session = Depends(get_db),
    payload: dict = Depends(require_user(UserType.ADMIN, UserType.PATIENT))
):
    # 从payload中获取用户类型和ID
    user_type = UserType.from_str(payload.get("user_type"))
    user_ref_id = int(payload.get("user_ref_id"))
    
    # 如果是患者，只能查看自己的记录
    if user_type == UserType.PATIENT and user_ref_id != patient_id:
        raise HTTPException(
            status_code=403, 
            detail="Patients can only view their own records"
        )
    
    return get_payments_by_patient(db, patient_id=patient_id)

@router.get("/patient/{patient_id}/paid", response_model=list[PaymentResponse])  # 获取已支付记录
def read_paid_patient_payments(
    patient_id: int,
    db: Session = Depends(get_db),
    payload: dict = Depends(require_user(UserType.ADMIN, UserType.PATIENT))
):
    user_type = UserType.from_str(payload.get("user_type"))
    user_ref_id = int(payload.get("user_ref_id"))

    if user_type == UserType.PATIENT and user_ref_id != patient_id:
        raise HTTPException(
            status_code=403,
            detail="Patients can only view their own paid records"
        )

    return get_paid_payments_by_patient(db, patient_id=patient_id)